#include "Descompresor"

Descompresor::Descompresor(ibitstream *is): archivoComoBits(*is) {
	_valorActual = 0;
	int i;
	//archivoComoBits.read((char*)&_valorActual,(USHORT_BIT/UCHAR_BIT));
}

void Descompresor::procesarBit() {

	int bitExtaido = archivoComoBits.get(); // TODO: no estoy teniendo en cuenta si viene EOF ¿que hago? Daniel dice: nada.
	//printf("leo bit: %i\n",bitExtaido);
	_valorActual = ((_valorActual<<1)&USHORT_MAX)|bitExtaido;

}

void Descompresor::procesarBitUnderFlow() {
	// tengo que sacar al SEGUNDO bit más significativo y agregar el del archivo al final
	int bitExtaido = archivoComoBits.get();
	//printf("leo bit: %i\n",bitExtaido);
		//_valorActual = ((_valorActual<<1)&USHORT_MAX)|bitExtaido;
	ushort guardoBit = (_valorActual&_medio);	// Guardo el bit de la izquierda
	ushort tmp = (((_valorActual<<1)|bitExtaido)<<1);  // Guardo temporalmente para "perder" el segundo bit
	_valorActual = ((tmp>>1)|guardoBit);
}

void Descompresor::renormalizar() {
	register bool continuar = true;
	while (continuar) {
        if (this->convergioAlTecho()||this->convergioAlPiso()) {
			this->renormalizarMaxBit();
			this->procesarBit();
		} else if(this->hayUnderflow()) {
			this->corregirUnderflow();
			this->procesarBitUnderFlow();
			//_techo = (((_techo<<1)&USHORT_MAX)|_medio)|1
			//_valorActual =(((_valorActual<<1)&USHORT_MAX)|_medio)>>1;
		} else
		{
            //esta normalizado
			continuar = false;
			//printf("Techo: %d, piso: %d, valor: %d\n",this->_techo, this->_piso, this->valorActual());
			break;
		}

        //this->procesarBit();
	}
}

ushort Descompresor::valorActual() {
	return _valorActual;
}

void Descompresor::procesarResultArit() {

}

/**Interfaz del Descompresor aritmetico con el Estructurado*/
ushort Descompresor::intervalo(ushort ft) {

	//ft = sumatoria total de frecuencias en el nivel
	//double rango = (double)(techo() - piso() + 1)/ft;
    //int intervalo = (int)(valorActual()- piso())/rango;

	// Utilizo la misma funcion que el compresor
	int i = 0;
	int auxPiso = damePiso(1,ft);
	while(auxPiso <= _valorActual){
		i++;
		auxPiso = damePiso(i+1,ft);
	}

	int intervalo = i;

	//printf("Techo: %d, piso: %d, valor: %d\n",this->_techo, this->_piso, this->valorActual());
	return (ushort)intervalo;
}
